package com.gozap.use;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ArrayQueue<E> {
	/** 锁 */
	private ReentrantLock lock;
	private Condition notFull;
	private Condition notEmpty;
	/** 存储对象 */
	private Store<E> store;

	public ArrayQueue(boolean fair, Store<E> s) {
		lock = new ReentrantLock(fair);
		notEmpty = lock.newCondition();
		notFull = lock.newCondition();
		this.store = s;
	}

	public ArrayQueue(boolean fair) {
		this(fair, null);
	}

	public void put(E e) throws InterruptedException {
		if (null == e) {
			throw new NullPointerException("the object to store can not be null");
		}
		lock.lock();
		try {
			while (store.isFull()) {
				notFull.await();
			}
			store.put(e);
			notEmpty.signal();
		} finally {
			lock.unlock();
		}
	}

	public E take() throws InterruptedException {
		lock.lock();
		try {
			while (0 == store.size()) {
				notEmpty.await();
			}
			notFull.signal();
			return store.take();
		} finally {
			lock.unlock();
		}
	}

	public int size() {
		lock.lock();
		try {
			return store.size();
		} finally {
			lock.unlock();
		}
	}

	public void setStore(Store<E> store) {
		this.store = store;
	}
}
